<?php


namespace services\buss;


use common\components\Service;
use common\helpers\CommonHelper;
use common\helpers\RedisHelper;
use common\models\base\Department;
use common\models\base\Project;
use common\models\base\Provinces;
use common\models\buss\Accounts;
use common\models\buss\AccountsConsume;
use common\models\buss\AccountsConsumeData;
use common\models\buss\Platform;
use common\models\member\Member;
use Exception;
use services\base\DepartmentService;
use services\log\LogMemberOpService;
use services\member\MemberService;
use Yii;

class AccountsConsumeService extends Service
{
    /**
     * 投流列表
     * @param array $params
     * @param int $page
     * @param int $pageSize
     * @return array
     */
    public function consumeList(array $params, int $page, int $pageSize): array
    {
        $query = AccountsConsume::find()
            ->alias('ac')
            ->select(['ac.*', 'a.account_name', 'a.nickname', 'a.project_id', 'a.department_id', 'a.platform_id', 'a.use_mid', 'a.status account_status', 'acd.private_sms_num', 'acd.effective_clue_num', 'acd.give_mobile_num', 'acd.recommend_num'])
            ->leftJoin(Accounts::tableName() . ' a', 'ac.account_id = a.id')
            ->leftJoin(AccountsConsumeData::tableName() . ' acd', 'acd.consume_id = ac.id')
            ->where(['ac.status' => AccountsConsume::STATUS_ENABLE]);

        // 权限【项目、部门】
        $memberAuth = MemberService::getLoginMemberLimit();
        // 是超管直接跳过
        if ($memberAuth['super_type'] != Member::SUPER_TYPE_SUPER_ADMIN) {
            // 是否为项目管理员
            if ($memberAuth['admin_project_ids']) {
                $query->andWhere([
                    'or',
                    ['a.project_id' => $memberAuth['admin_project_ids']],// 是【一个或几个】项目管理员则查全项目数据
                    [
                        'a.department_id' => $memberAuth['all_department_ids'],
                        'a.project_id' => $memberAuth['member_project_ids'],
                        'a.use_mid' => $memberAuth['all_member_ids'],
                    ]
                ]);
            } else {
                $query->andWhere([
                    'a.department_id' => $memberAuth['all_department_ids'],
                    'a.project_id' => $memberAuth['member_project_ids'],
                    'a.use_mid' => $memberAuth['all_member_ids'],
                ]);
            }
        }

        // 账号ID【账号消费必传，投流列表不传】
        if (isset($params['id']) && $params['id']) {
            $query->andWhere(['ac.account_id' => $params['id']]);
        }
        // 投流开始时间
        if (isset($params['date_stime']) && $params['date_stime']) {
            $query->andWhere(['>=', 'ac.date_time', strtotime($params['date_stime'])]);
        }
        // 投流结束时间
        if (isset($params['date_etime']) && $params['date_etime']) {
            $query->andWhere(['<=', 'ac.date_time', strtotime($params['date_etime'] . ' 23:59:59')]);
        }
        // 搜索账号昵称/账号名称
        if (isset($params['keywords']) && $params['keywords']) {
            $query->andWhere([
                'or',
                ['like', 'a.account_name', "{$params['keywords']}%", false],
                ['like', 'a.nickname', $params['keywords']]
            ]);
        }
        // 项目
        if (isset($params['project_id']) && $params['project_id']) {
            $query->andWhere(['a.project_id' => $params['project_id']]);
        }
        // 平台
        if (isset($params['platform_id']) && $params['platform_id']) {
            $query->andWhere(['a.platform_id' => $params['platform_id']]);
        }
        // 运营人
        if (isset($params['use_mid']) && $params['use_mid']) {
            $query->andWhere(['a.use_mid' => $params['use_mid']]);
        }
        // 部门
        if (isset($params['department_id']) && $params['department_id']) {
            $allIds = $params['department_id'];
            $department = RedisHelper::getDepartment($params['department_id']);
            if ($department->data_level == Department::DATA_LEVEL_DEPARTMENT_ALL) {
                $childDepartmentList = DepartmentService::getChildDepartmentList($department->tree_id);
                $allIds = array_merge([$department->id], array_column($childDepartmentList, 'id'));
            }
            $query->andWhere(['a.department_id' => $allIds]);
        }

        $orderBy = [];
        if (isset($params['order_column']) && $params['order_column']) {
            $sort = isset($params['order_sort']) && $params['order_sort'] == 'asc' ? SORT_ASC : SORT_DESC;
            switch ($params['order_column']) {
                case 'money':
                case 'date_time':
                case 'hours':
                case 'type':
                case 'private_sms_num':
                case 'effective_clue_num':
                case 'give_mobile_num':
                case 'recommend_num':
                    $orderBy[$params['order_column']] = $sort;
                    break;
                default :
                    break;
            }
        }
        $orderBy['ac.status'] = SORT_DESC;
        $orderBy['ac.date_time'] = SORT_DESC;
        $orderBy['ac.id'] = SORT_DESC;

        $list = $this->getListPageRes($query, $page, $pageSize, $orderBy);
        foreach ($list['list'] as &$val) {
            $platform = $val['platform_id'] ? RedisHelper::getPlatform($val['platform_id']) : '';
            $val['platform_name'] = $platform && $platform->status != Platform::STATUS_DELETE ? $platform->name : '';
            $project = $val['project_id'] ? RedisHelper::getProject($val['project_id']) : '';
            $val['project_name'] = $project && $project->status != Project::STATUS_DELETE ? $project->project_name : '';
            $department = $val['department_id'] ? RedisHelper::getDepartment($val['department_id']) : '';
            $val['department_name'] = $department && $department->status != Department::STATUS_DELETE ? $department->department_name : '';
            $member = $val['use_mid'] ? RedisHelper::getMember($val['use_mid']) : '';
            $val['use_mname'] = $member && $member->status != Member::STATUS_DELETE ? $member->realname : '';
            $val['date_time_str'] = $val['date_time'] ? date('Y-m-d', $val['date_time']) : '';
            $val['type_str'] = AccountsConsume::$types[$val['type']];
        }
        return $list;
    }

    /**
     * 投放类型下拉筛选项
     * @return array[]
     */
    public static function getTypesCondition(): array
    {
        return [
            ['value' => AccountsConsume::TYPE_FANS, 'label' => AccountsConsume::$types[AccountsConsume::TYPE_FANS]],
            ['value' => AccountsConsume::TYPE_VIEWS, 'label' => AccountsConsume::$types[AccountsConsume::TYPE_VIEWS]],
            ['value' => AccountsConsume::TYPE_LIKE, 'label' => AccountsConsume::$types[AccountsConsume::TYPE_LIKE]],
            ['value' => AccountsConsume::TYPE_SEE, 'label' => AccountsConsume::$types[AccountsConsume::TYPE_SEE]],
            ['value' => AccountsConsume::TYPE_HEAD_CLICK, 'label' => AccountsConsume::$types[AccountsConsume::TYPE_HEAD_CLICK]],
        ];
    }

    /**
     * 获取编辑筛选项
     * @param int|null $steam
     * @param array|int|null $orIds
     * @return array
     */
    public static function getEditCondition(int $steam, $orIds = null): array
    {
        return CommonHelper::getListCondition(AccountsService::getEnableListBySteam($steam, $orIds), ['value_column' => 'id', 'label_column' => 'nickname']);
    }

    /**
     * 新增消费
     */
    public function createConsume(array $params): array
    {
        if (Accounts::findOne($params['account_id'])->is_stream != Accounts::IS_STREAM_YES) {
            return CommonHelper::api(422, '账号未投流，不能录入消费');
        }
        $transaction = Yii::$app->db->beginTransaction();
        try {
            // 新增投流记录
            $consume = new AccountsConsume();
            $cityArr = is_array($params['city_id']) ? $params['city_id'] : explode(',', $params['city_id']);
            $cityNameArr = Provinces::find()->select(['title'])->where(['id' => $cityArr])->asArray()->column();
            $account = $this->getAccount($cityNameArr, $consume, $params);
            // 添加日志
            LogMemberOpService::createAccountLog('create_consume', $account, null, null, $consume);

            $transaction->commit();
            return ['account_id' => $consume->account_id];
        } catch (Exception $e) {
            $transaction->rollBack();
            throw $e;
        }
    }

    /**
     * 编辑消费
     * @throws \yii\db\Exception
     */
    public function updateConsume(array $params): array
    {
        if (Accounts::findOne($params['account_id'])->is_stream != Accounts::IS_STREAM_YES) {
            return CommonHelper::api(422, '账号未投流，不能录入消费');
        }
        $transaction = Yii::$app->db->beginTransaction();
        try {
            // 编辑投流记录
            $oldConsume = AccountsConsume::findOne($params['id']);
            $consume = AccountsConsume::findOne($params['id']);
            $cityArr = explode(',', $params['city_id']);
            $cityNameArr = Provinces::find()->select(['title'])->where(['id' => $cityArr])->asArray()->column();
            $account = $this->getAccount($cityNameArr, $consume, $params);
            // 添加日志
            LogMemberOpService::createAccountLog('update_consume', $account, null, null, $consume, $oldConsume);

            $transaction->commit();
            return ['account_id' => $consume->account_id];
        } catch (Exception $e) {
            $transaction->rollBack();
            throw $e;
        }
    }

    /**
     * 新增编辑账号投流消费后结果数据
     * @param array $params
     * @return int
     * @throws Exception
     */
    public function updateConsumeData(array $params): int
    {
        $data = AccountsConsumeData::findOne(['consume_id' => $params['consume_id']]);
        if (!$data) {
            $data = new AccountsConsumeData();
        }
        $data->consume_id = $params['consume_id'];
        $data->effective_clue_num = $params['effective_clue_num'] ?? '';
        $data->private_sms_num = $params['private_sms_num'] ?? '';
        $data->give_mobile_num = $params['give_mobile_num'] ?? '';
        $data->recommend_num = $params['recommend_num'] ?? '';
        $data->operation_id = Yii::$app->user->identity->member_id;
        $data->operation_name = Yii::$app->user->identity->member->realname;
        $data->saveAndCheckResult();
        $consume = AccountsConsume::findOne($params['consume_id']);
        // 添加日志
        LogMemberOpService::createAccountLog('update_consume_data', Accounts::findOne($consume->account_id), null, null, $consume, null, $data);
        return $data->consume_id;
    }

    /**
     * 删除消费
     * @param int $consumeId
     * @return int[]
     * @throws \yii\db\Exception
     */
    public function deleteConsume(int $consumeId): array
    {
        $transaction = Yii::$app->db->beginTransaction();
        try {
            $consume = AccountsConsume::findOne($consumeId);
            $consumeData = AccountsConsumeData::findOne(['consume_id' => $consumeId]);
            $account = Accounts::findOne($consume->account_id);
            // 添加日志
            LogMemberOpService::createAccountLog('delete_consume', $account, null, null, $consume, null, $consumeData);
            AccountsConsume::deleteAll(['id' => $consumeId]);
            AccountsConsumeData::deleteAll(['consume_id' => $consumeId]);
            $transaction->commit();
            return ['id' => $consumeId];
        } catch (\Exception $e) {
            $transaction->rollBack();
            throw $e;
        }
    }

    /**
     * @param array $cityNameArr
     * @param AccountsConsume $consume
     * @param array $params
     * @return Accounts|null
     * @throws Exception
     */
    public function getAccount(array $cityNameArr, AccountsConsume $consume, array $params): ?Accounts
    {
        $consume->account_id = $params['account_id'];
        $consume->date_time = strtotime($params['date_time']);
        $consume->money = $params['money'];
        $consume->city_id = $params['city_id'];
        $consume->city_name = implode(',', $cityNameArr);
        $consume->hours = $params['hours'];
        $consume->type = $params['type'];
        $consume->hour_minute = $params['hour_minute'];
        $consume->status = $params['status'] ?? AccountsConsume::STATUS_ENABLE;
        $consume->is_master = $params['is_master'] ?? AccountsConsume::IS_MASTER_NO;
        $consume->operation_id = Yii::$app->user->identity->member_id;
        $consume->operation_name = Yii::$app->user->identity->member->realname;
        $consume->saveAndCheckResult();

        return Accounts::findOne($params['account_id']);
    }
}
